2 * Routines for protocol tree
4 * $Id: proto.c,v 1.53 2002/02/18 22:26:29 guy Exp $
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.
29 #ifdef HAVE_SYS_TYPES_H
30 # include <sys/types.h>
37 #ifdef NEED_SNPRINTF_H
38 # include "snprintf.h"
45 #include "ipv6-utils.h"
47 #include "int-64bit.h"
49 #define cVALS(x) (const value_string*)(x)
52 proto_tree_free_node(GNode *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_int64(field_info *fi, gchar *label_str);
58 static void fill_label_enumerated_uint(field_info *fi, gchar *label_str);
59 static void fill_label_enumerated_bitfield(field_info *fi, gchar *label_str);
60 static void fill_label_numeric_bitfield(field_info *fi, gchar *label_str);
61 static void fill_label_int(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_int_vals_format(header_field_info *hfinfo);
68 static char* hfinfo_int_format(header_field_info *hfinfo);
70 static gboolean check_for_protocol_or_field_id(GNode *node, gpointer data);
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_uint64(field_info *fi, const guint8 *value_ptr, gboolean little_endian);
91 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian);
93 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
95 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
97 proto_tree_set_time(field_info *fi, nstime_t *value_ptr);
99 proto_tree_set_string(field_info *fi, const char* value);
101 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
103 proto_tree_set_ether(field_info *fi, const guint8* value);
105 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
107 proto_tree_set_ipxnet(field_info *fi, guint32 value);
109 proto_tree_set_ipv4(field_info *fi, guint32 value);
111 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
113 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start);
115 proto_tree_set_boolean(field_info *fi, guint32 value);
117 proto_tree_set_double(field_info *fi, double value);
119 proto_tree_set_uint(field_info *fi, guint32 value);
121 proto_tree_set_int(field_info *fi, gint32 value);
123 static int proto_register_field_init(header_field_info *hfinfo, int parent);
125 /* special-case header field used within proto.c */
126 int hf_text_only = 1;
128 /* Structure for information about a protocol */
130 char *name; /* long description */
131 char *short_name; /* short description */
132 char *filter_name; /* name of this protocol in filters */
133 int proto_id; /* field ID for this protocol */
134 GList *fields; /* fields for this protocol */
135 GList *last_field; /* pointer to end of list of fields */
136 gboolean is_enabled; /* TRUE if protocol is enabled */
137 gboolean can_disable; /* TRUE if protocol can be disabled */
140 /* List of all protocols */
141 static GList *protocols;
143 #define INITIAL_NUM_PROTOCOL_HFINFO 200
144 #define INITIAL_NUM_FIELD_INFO 100
145 #define INITIAL_NUM_PROTO_NODE 100
146 #define INITIAL_NUM_ITEM_LABEL 100
149 /* Contains information about protocols and header fields. Used when
150 * dissectors register their data */
151 static GMemChunk *gmc_hfinfo = NULL;
153 /* Contains information about a field when a dissector calls
154 * proto_tree_add_item. */
155 static GMemChunk *gmc_field_info = NULL;
157 /* Contains the space for proto_nodes. */
158 static GMemChunk *gmc_proto_node = NULL;
160 /* String space for protocol and field items for the GUI */
161 static GMemChunk *gmc_item_labels = NULL;
163 /* List which stores protocols and fields that have been registered */
164 static GPtrArray *gpa_hfinfo = NULL;
166 /* Points to the first element of an array of Booleans, indexed by
167 a subtree item type; that array element is TRUE if subtrees of
168 an item of that type are to be expanded. */
169 gboolean *tree_is_expanded;
171 /* Number of elements in that array. */
174 /* initialize data structures and register protocols and fields */
176 proto_init(const char *plugin_dir,void (register_all_protocols)(void),
177 void (register_all_protocol_handoffs)(void))
179 static hf_register_info hf[] = {
181 { "", "", FT_NONE, BASE_NONE, NULL, 0x0,
186 g_mem_chunk_destroy(gmc_hfinfo);
188 g_mem_chunk_destroy(gmc_field_info);
190 g_mem_chunk_destroy(gmc_proto_node);
192 g_mem_chunk_destroy(gmc_item_labels);
194 g_ptr_array_free(gpa_hfinfo, TRUE);
195 if (tree_is_expanded != NULL)
196 g_free(tree_is_expanded);
198 gmc_hfinfo = g_mem_chunk_new("gmc_hfinfo",
199 sizeof(header_field_info),
200 INITIAL_NUM_PROTOCOL_HFINFO * sizeof(header_field_info),
203 gmc_field_info = g_mem_chunk_new("gmc_field_info",
205 INITIAL_NUM_FIELD_INFO * sizeof(field_info),
208 gmc_proto_node = g_mem_chunk_new("gmc_proto_node",
210 INITIAL_NUM_PROTO_NODE * sizeof(proto_node),
213 gmc_item_labels = g_mem_chunk_new("gmc_item_labels",
215 INITIAL_NUM_ITEM_LABEL* ITEM_LABEL_LENGTH,
218 gpa_hfinfo = g_ptr_array_new();
220 /* Allocate "tree_is_expanded", with one element for ETT_NONE,
221 and initialize that element to FALSE. */
222 tree_is_expanded = g_malloc(sizeof (gint));
223 tree_is_expanded[0] = FALSE;
226 /* Initialize the ftype subsystem */
229 /* Have each built-in dissector register its protocols, fields,
230 dissector tables, and dissectors to be called through a
231 handle, and do whatever one-time initialization it needs to
233 register_all_protocols();
236 /* Now scan for plugins and load all the ones we find, calling
237 their register routines to do the stuff described above. */
238 init_plugins(plugin_dir);
241 /* Now call the "handoff registration" routines of all built-in
242 dissectors; those routines register the dissector in other
243 dissectors' handoff tables, and fetch any dissector handles
245 register_all_protocol_handoffs();
248 /* Now do the same with plugins. */
249 register_all_plugin_handoffs();
252 /* Register one special-case FT_TEXT_ONLY field for use when
253 converting ethereal to new-style proto_tree. These fields
254 are merely strings on the GUI tree; they are not filterable */
255 proto_register_field_array(-1, hf, array_length(hf));
257 /* We've assigned all the subtree type values; allocate the array
258 for them, and zero it out. */
259 tree_is_expanded = g_malloc(num_tree_types*sizeof (gint *));
260 memset(tree_is_expanded, '\0', num_tree_types*sizeof (gint *));
267 g_mem_chunk_destroy(gmc_hfinfo);
269 g_mem_chunk_destroy(gmc_field_info);
271 g_mem_chunk_destroy(gmc_proto_node);
273 g_mem_chunk_destroy(gmc_item_labels);
275 g_ptr_array_free(gpa_hfinfo, TRUE);
276 if (tree_is_expanded != NULL)
277 g_free(tree_is_expanded);
279 /* Cleanup the ftype subsystem */
283 /* frees the resources that the dissection a proto_tree uses */
285 proto_tree_free(proto_tree *tree)
287 /* Free all the data pointed to by the tree. */
288 g_node_traverse((GNode*)tree, G_IN_ORDER, G_TRAVERSE_ALL, -1,
289 proto_tree_free_node, NULL);
291 /* Then free the tree. */
292 g_node_destroy((GNode*)tree);
295 /* We accept a void* instead of a field_info* to satisfy CLEANUP_POP */
297 free_field_info(void *fi)
299 g_mem_chunk_free(gmc_field_info, (field_info*)fi);
303 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data)
305 GPtrArray *ptrs = value;
307 g_ptr_array_free(ptrs, TRUE);
311 free_node_tree_data(tree_data_t *tree_data)
313 /* Free all the GPtrArray's in the interesting_hfids hash. */
314 g_hash_table_foreach(tree_data->interesting_hfids,
315 free_GPtrArray_value, NULL);
317 /* And then destroy the hash. */
318 g_hash_table_destroy(tree_data->interesting_hfids);
320 /* And finally the tree_data_t itself. */
325 free_node_field_info(field_info* finfo)
327 if (finfo->representation) {
328 g_mem_chunk_free(gmc_item_labels, finfo->representation);
330 fvalue_free(finfo->value);
331 free_field_info(finfo);
335 proto_tree_free_node(GNode *node, gpointer data)
337 field_info *finfo = PITEM_FINFO(node);
340 /* This is the root GNode. Destroy the per-tree data.
341 * There is no field_info to destroy. */
342 free_node_tree_data(PTREE_DATA(node));
345 /* This is a child GNode. Don't free the per-tree data, but
346 * do free the field_info data. */
347 free_node_field_info(finfo);
350 /* Free the proto_node. */
351 g_mem_chunk_free(gmc_proto_node, GNODE_PNODE(node));
353 return FALSE; /* FALSE = do not end traversal of GNode tree */
356 /* Is the parsing being done for a visible proto_tree or an invisible one?
357 * By setting this correctly, the proto_tree creation is sped up by not
358 * having to call vsnprintf and copy strings around.
361 proto_tree_set_visible(proto_tree *tree, gboolean visible)
363 PTREE_DATA(tree)->visible = visible;
366 /* Finds a record in the hf_info_records array by id. */
368 proto_registrar_get_nth(int hfindex)
370 g_assert(hfindex >= 0 && (guint) hfindex < gpa_hfinfo->len);
371 return g_ptr_array_index(gpa_hfinfo, hfindex);
375 /* Add a text-only node, leaving it to our caller to fill the text in */
377 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
381 pi = proto_tree_add_pi(tree, hf_text_only, tvb, start, &length, NULL);
388 /* Add a text-only node to the proto_tree */
390 proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
391 const char *format, ...)
396 pi = proto_tree_add_text_node(tree, tvb, start, length);
400 va_start(ap, format);
401 proto_tree_set_representation(pi, format, ap);
407 /* Add a text-only node to the proto_tree (va_list version) */
409 proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
410 gint length, const char *format, va_list ap)
414 pi = proto_tree_add_text_node(tree, tvb, start, length);
418 proto_tree_set_representation(pi, format, ap);
423 /* Add a text-only node for debugging purposes. The caller doesn't need
424 * to worry about tvbuff, start, or length. Debug message gets sent to
427 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
432 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
436 va_start(ap, format);
437 proto_tree_set_representation(pi, format, ap);
447 get_uint_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
454 value = tvb_get_guint8(tvb, offset);
458 value = little_endian ? tvb_get_letohs(tvb, offset)
459 : tvb_get_ntohs(tvb, offset);
463 value = little_endian ? tvb_get_letoh24(tvb, offset)
464 : tvb_get_ntoh24(tvb, offset);
468 value = little_endian ? tvb_get_letohl(tvb, offset)
469 : tvb_get_ntohl(tvb, offset);
473 g_assert_not_reached();
481 get_int_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
488 value = (gint8)tvb_get_guint8(tvb, offset);
492 value = (gint16) (little_endian ? tvb_get_letohs(tvb, offset)
493 : tvb_get_ntohs(tvb, offset));
497 value = little_endian ? tvb_get_letoh24(tvb, offset)
498 : tvb_get_ntoh24(tvb, offset);
499 if (value & 0x00800000) {
500 /* Sign bit is set; sign-extend it. */
506 value = little_endian ? tvb_get_letohl(tvb, offset)
507 : tvb_get_ntohl(tvb, offset);
511 g_assert_not_reached();
518 /* Add an item to a proto_tree, using the text label registered to that item;
519 the item is extracted from the tvbuff handed to it. */
521 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
522 gint start, gint length, gboolean little_endian)
535 new_fi = alloc_field_info(tree, hfindex, tvb, start, &length);
540 /* Register a cleanup function in case on of our tvbuff accesses
541 * throws an exception. We need to clean up new_fi. */
542 CLEANUP_PUSH(free_field_info, new_fi);
544 switch(new_fi->hfinfo->type) {
546 /* no value to set for FT_NONE */
550 proto_tree_set_protocol_tvb(new_fi, tvb);
554 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
558 proto_tree_set_boolean(new_fi,
559 get_uint_value(tvb, start, length, little_endian));
562 /* XXX - make these just FT_UINT? */
567 proto_tree_set_uint(new_fi,
568 get_uint_value(tvb, start, length, little_endian));
573 g_assert(length == 8);
574 proto_tree_set_uint64_tvb(new_fi, tvb, start, little_endian);
577 /* XXX - make these just FT_INT? */
582 proto_tree_set_int(new_fi,
583 get_int_value(tvb, start, length, little_endian));
587 g_assert(length == 4);
588 tvb_memcpy(tvb, (guint8 *)&value, start, 4);
589 proto_tree_set_ipv4(new_fi, value);
593 g_assert(length == 4);
594 proto_tree_set_ipxnet(new_fi,
595 get_uint_value(tvb, start, 4, FALSE));
599 g_assert(length == 16);
600 proto_tree_set_ipv6_tvb(new_fi, tvb, start);
604 g_assert(length == 6);
605 proto_tree_set_ether_tvb(new_fi, tvb, start);
609 /* This g_strdup'ed memory is freed in proto_tree_free_node() */
610 proto_tree_set_string_tvb(new_fi, tvb, start, length);
614 /* This g_strdup'ed memory is freed in proto_tree_free_node() */
615 string = g_malloc(length);
617 CLEANUP_PUSH(g_free, string);
619 found_length = tvb_get_nstringz(tvb, start, length, string);
620 if (found_length < 1) {
621 found_length = tvb_get_nstringz0(tvb, start, length, string);
626 proto_tree_set_string(new_fi, string);
627 new_fi->length = found_length + 1;
632 /* This g_strdup'ed memory is freed in proto_tree_free_node() */
633 n = get_uint_value(tvb, start, length, little_endian);
634 proto_tree_set_string_tvb(new_fi, tvb, start + length, n);
636 /* Instead of calling proto_item_set_len(), since we don't yet
637 * have a proto_item, we set the field_info's length ourselves. */
638 new_fi->length = n + length;
641 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
642 new_fi->hfinfo->type,
643 ftype_name(new_fi->hfinfo->type));
644 g_assert_not_reached();
650 /* Don't add to proto_item to proto_tree until now so that any exceptions
651 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
652 pi = proto_tree_add_node(tree, new_fi);
654 /* If the proto_tree wants to keep a record of this finfo
655 * for quick lookup, then record it. */
656 hash = PTREE_DATA(tree)->interesting_hfids;
657 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
659 g_ptr_array_add(ptrs, new_fi);
666 proto_tree_add_item_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb,
667 gint start, gint length, gboolean little_endian)
672 pi = proto_tree_add_item(tree, hfindex, tvb, start, length, little_endian);
676 fi = PITEM_FINFO(pi);
683 /* Add a FT_NONE to a proto_tree */
685 proto_tree_add_none_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
686 gint length, const char *format, ...)
690 header_field_info *hfinfo;
695 hfinfo = proto_registrar_get_nth(hfindex);
696 g_assert(hfinfo->type == FT_NONE);
698 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, NULL);
700 va_start(ap, format);
701 proto_tree_set_representation(pi, format, ap);
704 /* no value to set for FT_NONE */
710 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
712 fvalue_set(fi->value, tvb, TRUE);
715 /* Add a FT_PROTOCOL to a proto_tree */
717 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
718 gint length, const char *format, ...)
722 header_field_info *hfinfo;
728 hfinfo = proto_registrar_get_nth(hfindex);
729 g_assert(hfinfo->type == FT_PROTOCOL);
731 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
733 va_start(ap, format);
734 proto_tree_set_representation(pi, format, ap);
738 proto_tree_set_protocol_tvb(new_fi, tvb);
741 proto_tree_set_protocol_tvb(new_fi, NULL);
747 /* Add a FT_BYTES to a proto_tree */
749 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
750 gint length, const guint8 *start_ptr)
754 header_field_info *hfinfo;
759 hfinfo = proto_registrar_get_nth(hfindex);
760 g_assert(hfinfo->type == FT_BYTES);
762 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
763 proto_tree_set_bytes(new_fi, start_ptr, length);
769 proto_tree_add_bytes_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
770 gint length, const guint8 *start_ptr)
775 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
779 fi = PITEM_FINFO(pi);
786 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
787 gint length, const guint8 *start_ptr, const char *format, ...)
792 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
796 va_start(ap, format);
797 proto_tree_set_representation(pi, format, ap);
804 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
808 bytes = g_byte_array_new();
810 g_byte_array_append(bytes, start_ptr, length);
812 fvalue_set(fi->value, bytes, TRUE);
817 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
819 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
822 /* Add a FT_*TIME to a proto_tree */
824 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
829 header_field_info *hfinfo;
834 hfinfo = proto_registrar_get_nth(hfindex);
835 g_assert(hfinfo->type == FT_ABSOLUTE_TIME ||
836 hfinfo->type == FT_RELATIVE_TIME);
838 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
839 proto_tree_set_time(new_fi, value_ptr);
845 proto_tree_add_time_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
851 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
855 fi = PITEM_FINFO(pi);
862 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
863 nstime_t *value_ptr, const char *format, ...)
868 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
872 va_start(ap, format);
873 proto_tree_set_representation(pi, format, ap);
879 /* Set the FT_*TIME value */
881 proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
883 fvalue_set(fi->value, value_ptr, FALSE);
886 /* Add a FT_IPXNET to a proto_tree */
888 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
893 header_field_info *hfinfo;
898 hfinfo = proto_registrar_get_nth(hfindex);
899 g_assert(hfinfo->type == FT_IPXNET);
901 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
902 proto_tree_set_ipxnet(new_fi, value);
908 proto_tree_add_ipxnet_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
914 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
918 fi = PITEM_FINFO(pi);
925 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
926 guint32 value, const char *format, ...)
931 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
935 va_start(ap, format);
936 proto_tree_set_representation(pi, format, ap);
942 /* Set the FT_IPXNET value */
944 proto_tree_set_ipxnet(field_info *fi, guint32 value)
946 fvalue_set_integer(fi->value, value);
949 /* Add a FT_IPv4 to a proto_tree */
951 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
956 header_field_info *hfinfo;
961 hfinfo = proto_registrar_get_nth(hfindex);
962 g_assert(hfinfo->type == FT_IPv4);
964 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
965 proto_tree_set_ipv4(new_fi, value);
971 proto_tree_add_ipv4_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
977 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
981 fi = PITEM_FINFO(pi);
988 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
989 guint32 value, const char *format, ...)
994 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
998 va_start(ap, format);
999 proto_tree_set_representation(pi, format, ap);
1005 /* Set the FT_IPv4 value */
1007 proto_tree_set_ipv4(field_info *fi, guint32 value)
1009 fvalue_set_integer(fi->value, value);
1012 /* Add a FT_IPv6 to a proto_tree */
1014 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1015 const guint8* value_ptr)
1019 header_field_info *hfinfo;
1024 hfinfo = proto_registrar_get_nth(hfindex);
1025 g_assert(hfinfo->type == FT_IPv6);
1027 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1028 proto_tree_set_ipv6(new_fi, value_ptr);
1034 proto_tree_add_ipv6_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1035 const guint8* value_ptr)
1040 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1044 fi = PITEM_FINFO(pi);
1045 fi->visible = FALSE;
1051 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1052 const guint8* value_ptr, const char *format, ...)
1057 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1061 va_start(ap, format);
1062 proto_tree_set_representation(pi, format, ap);
1068 /* Set the FT_IPv6 value */
1070 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
1072 fvalue_set(fi->value, (gpointer) value_ptr, FALSE);
1076 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start)
1078 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, 16));
1082 proto_tree_set_uint64(field_info *fi, const guint8 *value_ptr, gboolean little_endian)
1085 unsigned char buffer[8];
1089 buffer[i]=value_ptr[7-i];
1091 fvalue_set(fi->value, (gpointer)buffer, FALSE);
1093 fvalue_set(fi->value, (gpointer)value_ptr, FALSE);
1098 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian)
1100 proto_tree_set_uint64(fi, tvb_get_ptr(tvb, start, 8), little_endian);
1103 /* Add a FT_STRING to a proto_tree */
1105 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1106 gint length, const char* value)
1110 header_field_info *hfinfo;
1115 hfinfo = proto_registrar_get_nth(hfindex);
1116 g_assert(hfinfo->type == FT_STRING);
1118 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1119 proto_tree_set_string(new_fi, value);
1125 proto_tree_add_string_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1126 gint length, const char* value)
1131 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
1135 fi = PITEM_FINFO(pi);
1136 fi->visible = FALSE;
1142 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1143 gint length, const char* value, const char *format, ...)
1148 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
1152 va_start(ap, format);
1153 proto_tree_set_representation(pi, format, ap);
1159 /* Set the FT_STRING value */
1161 proto_tree_set_string(field_info *fi, const char* value)
1163 fvalue_set(fi->value, (gpointer) value, FALSE);
1167 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
1172 length = tvb_ensure_length_remaining(tvb, start);
1175 /* This memory is freed in proto_tree_free_node() */
1176 string = g_malloc(length + 1);
1177 tvb_memcpy(tvb, string, start, length);
1178 string[length] = '\0';
1179 fvalue_set(fi->value, string, TRUE);
1182 /* Add a FT_ETHER to a proto_tree */
1184 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1185 const guint8* value)
1189 header_field_info *hfinfo;
1194 hfinfo = proto_registrar_get_nth(hfindex);
1195 g_assert(hfinfo->type == FT_ETHER);
1197 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1198 proto_tree_set_ether(new_fi, value);
1204 proto_tree_add_ether_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1205 const guint8* value)
1210 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
1214 fi = PITEM_FINFO(pi);
1215 fi->visible = FALSE;
1221 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1222 const guint8* value, const char *format, ...)
1227 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
1231 va_start(ap, format);
1232 proto_tree_set_representation(pi, format, ap);
1238 /* Set the FT_ETHER value */
1240 proto_tree_set_ether(field_info *fi, const guint8* value)
1242 fvalue_set(fi->value, (gpointer) value, FALSE);
1246 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
1248 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, 6));
1251 /* Add a FT_BOOLEAN to a proto_tree */
1253 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1258 header_field_info *hfinfo;
1263 hfinfo = proto_registrar_get_nth(hfindex);
1264 g_assert(hfinfo->type == FT_BOOLEAN);
1266 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1267 proto_tree_set_boolean(new_fi, value);
1273 proto_tree_add_boolean_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1279 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
1283 fi = PITEM_FINFO(pi);
1284 fi->visible = FALSE;
1290 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1291 guint32 value, const char *format, ...)
1296 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
1300 va_start(ap, format);
1301 proto_tree_set_representation(pi, format, ap);
1307 /* Set the FT_BOOLEAN value */
1309 proto_tree_set_boolean(field_info *fi, guint32 value)
1311 proto_tree_set_uint(fi, value);
1314 /* Add a FT_DOUBLE to a proto_tree */
1316 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1321 header_field_info *hfinfo;
1326 hfinfo = proto_registrar_get_nth(hfindex);
1327 g_assert(hfinfo->type == FT_DOUBLE);
1329 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1330 proto_tree_set_double(new_fi, value);
1336 proto_tree_add_double_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1342 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
1346 fi = PITEM_FINFO(pi);
1347 fi->visible = FALSE;
1353 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1354 double value, const char *format, ...)
1359 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
1363 va_start(ap, format);
1364 proto_tree_set_representation(pi, format, ap);
1370 /* Set the FT_DOUBLE value */
1372 proto_tree_set_double(field_info *fi, double value)
1374 fvalue_set_floating(fi->value, value);
1377 /* Add any FT_UINT* to a proto_tree */
1379 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1382 proto_item *pi = NULL;
1384 header_field_info *hfinfo;
1389 hfinfo = proto_registrar_get_nth(hfindex);
1390 switch(hfinfo->type) {
1395 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
1397 proto_tree_set_uint(new_fi, value);
1401 g_assert_not_reached();
1408 proto_tree_add_uint_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1414 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
1418 fi = PITEM_FINFO(pi);
1419 fi->visible = FALSE;
1425 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1426 guint32 value, const char *format, ...)
1431 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
1435 va_start(ap, format);
1436 proto_tree_set_representation(pi, format, ap);
1442 /* Set the FT_UINT* value */
1444 proto_tree_set_uint(field_info *fi, guint32 value)
1446 header_field_info *hfinfo;
1449 hfinfo = fi->hfinfo;
1452 if (hfinfo->bitmask) {
1453 /* Mask out irrelevant portions */
1454 integer &= hfinfo->bitmask;
1457 if (hfinfo->bitshift > 0) {
1458 integer >>= hfinfo->bitshift;
1461 fvalue_set_integer(fi->value, integer);
1464 /* Add any FT_INT* to a proto_tree */
1466 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1469 proto_item *pi = NULL;
1471 header_field_info *hfinfo;
1476 hfinfo = proto_registrar_get_nth(hfindex);
1477 switch(hfinfo->type) {
1482 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
1484 proto_tree_set_int(new_fi, value);
1488 g_assert_not_reached();
1495 proto_tree_add_int_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1501 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
1505 fi = PITEM_FINFO(pi);
1506 fi->visible = FALSE;
1512 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1513 gint32 value, const char *format, ...)
1515 proto_item *pi = NULL;
1518 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
1522 va_start(ap, format);
1523 proto_tree_set_representation(pi, format, ap);
1529 /* Set the FT_INT* value */
1531 proto_tree_set_int(field_info *fi, gint32 value)
1533 header_field_info *hfinfo;
1536 hfinfo = fi->hfinfo;
1537 integer = (guint32) value;
1539 if (hfinfo->bitmask) {
1540 /* Mask out irrelevant portions */
1541 integer &= hfinfo->bitmask;
1544 if (hfinfo->bitshift > 0) {
1545 integer >>= hfinfo->bitshift;
1548 fvalue_set_integer(fi->value, integer);
1552 /* Add a field_info struct to the proto_tree, encapsulating it in a GNode (proto_item) */
1554 proto_tree_add_node(proto_tree *tree, field_info *fi)
1559 pnode = g_mem_chunk_alloc(gmc_proto_node);
1561 pnode->tree_data = PTREE_DATA(tree);
1563 new_gnode = g_node_new(pnode);
1564 g_node_append((GNode*)tree, new_gnode);
1566 return (proto_item*) new_gnode;
1570 /* Generic way to allocate field_info and add to proto_tree.
1571 * Sets *pfi to address of newly-allocated field_info struct, if pfi is
1574 proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1575 gint *length, field_info **pfi)
1585 fi = alloc_field_info(tree, hfindex, tvb, start, length);
1586 pi = proto_tree_add_node(tree, fi);
1588 /* If the proto_tree wants to keep a record of this finfo
1589 * for quick lookup, then record it. */
1590 hash = PTREE_DATA(tree)->interesting_hfids;
1591 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
1593 g_ptr_array_add(ptrs, fi);
1596 /* Does the caller want to know the fi pointer? */
1605 alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1608 header_field_info *hfinfo;
1612 * We only allow a null tvbuff if the item has a zero length,
1613 * i.e. if there's no data backing it.
1615 g_assert(tvb != NULL || *length == 0);
1617 g_assert(hfindex >= 0 && (guint) hfindex < gpa_hfinfo->len);
1618 hfinfo = proto_registrar_get_nth(hfindex);
1619 g_assert(hfinfo != NULL);
1621 if (*length == -1) {
1623 * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
1624 * a length of -1 means "set the length to what remains in
1627 * The assumption is either that
1629 * 1) the length of the item can only be determined
1630 * by dissection (typically true of items with
1631 * subitems, which are probably FT_NONE or
1636 * 2) if the tvbuff is "short" (either due to a short
1637 * snapshot length or due to lack of reassembly of
1638 * fragments/segments/whatever), we want to display
1639 * what's available in the field (probably FT_BYTES
1640 * or FT_STRING) and then throw an exception later
1644 * 3) the field is defined to be "what's left in the
1647 * so we set the length to what remains in the tvbuff so
1648 * that, if we throw an exception while dissecting, it
1649 * has what is probably the right value.
1651 * It's not valid for any other type of field.
1653 g_assert(hfinfo->type == FT_PROTOCOL ||
1654 hfinfo->type == FT_NONE ||
1655 hfinfo->type == FT_BYTES ||
1656 hfinfo->type == FT_STRING);
1657 *length = tvb_ensure_length_remaining(tvb, start);
1660 fi = g_mem_chunk_alloc(gmc_field_info);
1661 fi->hfinfo = hfinfo;
1664 fi->start += tvb_raw_offset(tvb);
1666 fi->length = *length;
1667 fi->tree_type = ETT_NONE;
1668 fi->visible = PTREE_DATA(tree)->visible;
1669 fi->representation = NULL;
1671 fi->value = fvalue_new(fi->hfinfo->type);
1673 /* add the data source tvbuff */
1675 fi->ds_tvb = tvb_get_ds_tvb(tvb);
1683 /* Set representation of a proto_tree entry, if the protocol tree is to
1686 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
1688 field_info *fi = PITEM_FINFO(pi);
1691 fi->representation = g_mem_chunk_alloc(gmc_item_labels);
1692 vsnprintf(fi->representation, ITEM_LABEL_LENGTH, format, ap);
1696 /* Set text of proto_item after having already been created. */
1698 proto_item_set_text(proto_item *pi, const char *format, ...)
1700 field_info *fi = NULL;
1707 fi = PITEM_FINFO(pi);
1709 if (fi->representation)
1710 g_mem_chunk_free(gmc_item_labels, fi->representation);
1712 va_start(ap, format);
1713 proto_tree_set_representation(pi, format, ap);
1717 /* Append to text of proto_item after having already been created. */
1719 proto_item_append_text(proto_item *pi, const char *format, ...)
1721 field_info *fi = NULL;
1729 fi = PITEM_FINFO(pi);
1732 va_start(ap, format);
1734 * XXX - this will blow up if we haven't already set
1735 * "fi->representation"; that seems OK to me - you
1736 * can't append to something that doesn't exist - but
1737 * there might be cases where that's not convenient.
1739 curlen = strlen(fi->representation);
1740 if (ITEM_LABEL_LENGTH > curlen)
1741 vsnprintf(fi->representation + curlen,
1742 ITEM_LABEL_LENGTH - curlen, format, ap);
1748 proto_item_set_len(proto_item *pi, gint length)
1754 fi = PITEM_FINFO(pi);
1755 fi->length = length;
1759 proto_item_get_len(proto_item *pi)
1761 field_info *fi = PITEM_FINFO(pi);
1766 proto_tree_create_root(void)
1770 /* Initialize the proto_node */
1771 pnode = g_mem_chunk_alloc(gmc_proto_node);
1772 pnode->finfo = NULL;
1773 pnode->tree_data = g_new(tree_data_t, 1);
1775 /* Initialize the tree_data_t */
1776 pnode->tree_data->interesting_hfids =
1777 g_hash_table_new(g_direct_hash, g_direct_equal);
1779 /* Set the default to FALSE so it's easier to
1780 * find errors; if we expect to see the protocol tree
1781 * but for some reason the default 'visible' is not
1782 * changed, then we'll find out very quickly. */
1783 pnode->tree_data->visible = FALSE;
1785 return (proto_tree*) g_node_new(pnode);
1789 proto_tree_prime_hfid(proto_tree *tree, int hfid)
1791 g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids,
1792 GINT_TO_POINTER(hfid), g_ptr_array_new());
1796 proto_item_add_subtree(proto_item *pi, gint idx) {
1802 fi = PITEM_FINFO(pi);
1803 g_assert(idx >= 0 && idx < num_tree_types);
1804 fi->tree_type = idx;
1805 return (proto_tree*) pi;
1809 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
1811 const protocol_t *p1 = p1_arg;
1812 const protocol_t *p2 = p2_arg;
1814 return g_strcasecmp(p1->short_name, p2->short_name);
1818 proto_register_protocol(char *name, char *short_name, char *filter_name)
1820 protocol_t *protocol;
1821 header_field_info *hfinfo;
1824 /* Add this protocol to the list of known protocols; the list
1825 is sorted by protocol short name. */
1826 protocol = g_malloc(sizeof (protocol_t));
1827 protocol->name = name;
1828 protocol->short_name = short_name;
1829 protocol->filter_name = filter_name;
1830 protocol->fields = NULL;
1831 protocol->is_enabled = TRUE; /* protocol is enabled by default */
1832 protocol->can_disable = TRUE;
1833 protocols = g_list_insert_sorted(protocols, protocol,
1834 proto_compare_name);
1836 /* Here we do allocate a new header_field_info struct */
1837 hfinfo = g_mem_chunk_alloc(gmc_hfinfo);
1838 hfinfo->name = name;
1839 hfinfo->abbrev = filter_name;
1840 hfinfo->type = FT_PROTOCOL;
1841 hfinfo->strings = NULL;
1842 hfinfo->bitmask = 0;
1843 hfinfo->bitshift = 0;
1845 hfinfo->parent = -1; /* this field differentiates protos and fields */
1847 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
1848 protocol->proto_id = proto_id;
1853 * Routines to use to iterate over the protocols.
1854 * The argument passed to the iterator routines is an opaque cookie to
1855 * their callers; it's the GList pointer for the current element in
1857 * The ID of the protocol is returned, or -1 if there is no protocol.
1860 proto_get_first_protocol(void **cookie)
1862 protocol_t *protocol;
1864 if (protocols == NULL)
1866 *cookie = protocols;
1867 protocol = protocols->data;
1868 return protocol->proto_id;
1872 proto_get_next_protocol(void **cookie)
1874 GList *list_item = *cookie;
1875 protocol_t *protocol;
1877 list_item = g_list_next(list_item);
1878 if (list_item == NULL)
1880 *cookie = list_item;
1881 protocol = list_item->data;
1882 return protocol->proto_id;
1886 * Find the protocol list entry for a protocol given its field ID.
1889 compare_proto_id(gconstpointer proto_arg, gconstpointer id_arg)
1891 const protocol_t *protocol = proto_arg;
1892 const int *id_ptr = id_arg;
1894 return (protocol->proto_id == *id_ptr) ? 0 : 1;
1898 find_protocol_by_id(int proto_id)
1902 list_entry = g_list_find_custom(protocols, &proto_id, compare_proto_id);
1903 if (list_entry == NULL)
1905 return list_entry->data;
1908 static gint compare_filter_name(gconstpointer proto_arg,
1909 gconstpointer filter_name)
1911 const protocol_t *protocol = proto_arg;
1912 const gchar* f_name = filter_name;
1913 return (strcmp(protocol->filter_name, f_name));
1916 int proto_get_id_by_filter_name(gchar* filter_name)
1919 protocol_t *protocol;
1920 list_entry = g_list_find_custom(protocols,filter_name,compare_filter_name);
1921 if(list_entry == NULL)
1923 protocol = list_entry->data;
1924 return(protocol->proto_id);
1928 proto_get_protocol_name(int proto_id)
1930 protocol_t *protocol;
1932 protocol = find_protocol_by_id(proto_id);
1933 return protocol->name;
1937 proto_get_protocol_short_name(int proto_id)
1939 protocol_t *protocol;
1943 protocol = find_protocol_by_id(proto_id);
1944 return protocol->short_name;
1948 proto_get_protocol_filter_name(int proto_id)
1950 protocol_t *protocol;
1952 protocol = find_protocol_by_id(proto_id);
1953 return protocol->filter_name;
1957 proto_is_protocol_enabled(int proto_id)
1959 protocol_t *protocol;
1961 protocol = find_protocol_by_id(proto_id);
1962 return protocol->is_enabled;
1966 proto_can_disable_protocol(int proto_id)
1968 protocol_t *protocol;
1970 protocol = find_protocol_by_id(proto_id);
1971 return protocol->can_disable;
1975 proto_set_decoding(int proto_id, gboolean enabled)
1977 protocol_t *protocol;
1979 protocol = find_protocol_by_id(proto_id);
1980 g_assert(enabled || protocol->can_disable);
1981 protocol->is_enabled = enabled;
1985 proto_set_cant_disable(int proto_id)
1987 protocol_t *protocol;
1989 protocol = find_protocol_by_id(proto_id);
1990 protocol->can_disable = FALSE;
1993 /* for use with static arrays only, since we don't allocate our own copies
1994 of the header_field_info struct contained withing the hf_register_info struct */
1996 proto_register_field_array(int parent, hf_register_info *hf, int num_records)
1999 hf_register_info *ptr = hf;
2002 proto = find_protocol_by_id(parent);
2003 for (i = 0; i < num_records; i++, ptr++) {
2004 if (proto != NULL) {
2005 if (proto->fields == NULL) {
2006 proto->fields = g_list_append(NULL, ptr);
2007 proto->last_field = proto->fields;
2010 g_list_append(proto->last_field, ptr)->next;
2013 field_id = proto_register_field_init(&ptr->hfinfo, parent);
2014 *ptr->p_id = field_id;
2019 proto_register_field_init(header_field_info *hfinfo, int parent)
2021 /* These types of fields are allowed to have value_strings or true_false_strings */
2022 g_assert((hfinfo->strings == NULL) || (
2023 (hfinfo->type == FT_UINT8) ||
2024 (hfinfo->type == FT_UINT16) ||
2025 (hfinfo->type == FT_UINT24) ||
2026 (hfinfo->type == FT_UINT32) ||
2027 (hfinfo->type == FT_INT8) ||
2028 (hfinfo->type == FT_INT16) ||
2029 (hfinfo->type == FT_INT24) ||
2030 (hfinfo->type == FT_INT32) ||
2031 (hfinfo->type == FT_BOOLEAN) ));
2033 /* Require integral types to have a number base */
2034 switch (hfinfo->type) {
2044 g_assert(hfinfo->display != BASE_NONE);
2050 /* if this is a bitfield, compure bitshift */
2051 if (hfinfo->bitmask) {
2052 while ((hfinfo->bitmask & (1 << hfinfo->bitshift)) == 0)
2056 hfinfo->parent = parent;
2057 hfinfo->same_name_next = NULL;
2058 hfinfo->same_name_prev = NULL;
2060 /* if we always add and never delete, then id == len - 1 is correct */
2061 g_ptr_array_add(gpa_hfinfo, hfinfo);
2062 hfinfo->id = gpa_hfinfo->len - 1;
2067 proto_register_subtree_array(gint **indices, int num_indices)
2070 gint **ptr = indices;
2073 * Add "num_indices" elements to "tree_is_expanded".
2075 tree_is_expanded = g_realloc(tree_is_expanded,
2076 (num_tree_types + num_indices)*sizeof (gint));
2079 * Assign "num_indices" subtree numbers starting at "num_tree_types",
2080 * returning the indices through the pointers in the array whose
2081 * first element is pointed to by "indices", set to FALSE the
2082 * elements to which those subtree numbers refer, and update
2083 * "num_tree_types" appropriately.
2085 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
2086 tree_is_expanded[num_tree_types] = FALSE;
2087 **ptr = num_tree_types;
2092 proto_item_fill_label(field_info *fi, gchar *label_str)
2094 header_field_info *hfinfo = fi->hfinfo;
2099 guint32 n_addr; /* network-order IPv4 address */
2101 switch(hfinfo->type) {
2104 snprintf(label_str, ITEM_LABEL_LENGTH,
2105 "%s", hfinfo->name);
2109 fill_label_boolean(fi, label_str);
2113 bytes = fvalue_get(fi->value);
2115 snprintf(label_str, ITEM_LABEL_LENGTH,
2116 "%s: %s", hfinfo->name,
2117 bytes_to_str(bytes, fi->length));
2120 snprintf(label_str, ITEM_LABEL_LENGTH,
2121 "%s: <MISSING>", hfinfo->name);
2125 /* Four types of integers to take care of:
2126 * Bitfield, with val_string
2127 * Bitfield, w/o val_string
2128 * Non-bitfield, with val_string
2129 * Non-bitfield, w/o val_string
2135 if (hfinfo->bitmask) {
2136 if (hfinfo->strings) {
2137 fill_label_enumerated_bitfield(fi, label_str);
2140 fill_label_numeric_bitfield(fi, label_str);
2144 if (hfinfo->strings) {
2145 fill_label_enumerated_uint(fi, label_str);
2148 fill_label_uint(fi, label_str);
2154 fill_label_uint64(fi, label_str);
2161 g_assert(!hfinfo->bitmask);
2162 if (hfinfo->strings) {
2163 fill_label_enumerated_int(fi, label_str);
2166 fill_label_int(fi, label_str);
2171 fill_label_int64(fi, label_str);
2175 snprintf(label_str, ITEM_LABEL_LENGTH,
2176 "%s: %g", hfinfo->name, fvalue_get_floating(fi->value));
2179 case FT_ABSOLUTE_TIME:
2180 snprintf(label_str, ITEM_LABEL_LENGTH,
2181 "%s: %s", hfinfo->name,
2182 abs_time_to_str(fvalue_get(fi->value)));
2185 case FT_RELATIVE_TIME:
2186 snprintf(label_str, ITEM_LABEL_LENGTH,
2187 "%s: %s seconds", hfinfo->name,
2188 rel_time_to_secs_str(fvalue_get(fi->value)));
2192 integer = fvalue_get_integer(fi->value);
2193 snprintf(label_str, ITEM_LABEL_LENGTH,
2194 "%s: 0x%08X (%s)", hfinfo->name,
2195 integer, get_ipxnet_name(integer));
2199 bytes = fvalue_get(fi->value);
2200 snprintf(label_str, ITEM_LABEL_LENGTH,
2201 "%s: %s (%s)", hfinfo->name,
2202 ether_to_str(bytes),
2203 get_ether_name(bytes));
2207 ipv4 = fvalue_get(fi->value);
2208 n_addr = ipv4_get_net_order_addr(ipv4);
2209 snprintf(label_str, ITEM_LABEL_LENGTH,
2210 "%s: %s (%s)", hfinfo->name,
2211 get_hostname(n_addr),
2212 ip_to_str((guint8*)&n_addr));
2216 bytes = fvalue_get(fi->value);
2217 snprintf(label_str, ITEM_LABEL_LENGTH,
2218 "%s: %s (%s)", hfinfo->name,
2219 get_hostname6((struct e_in6_addr *)bytes),
2220 ip6_to_str((struct e_in6_addr*)bytes));
2225 case FT_UINT_STRING:
2226 snprintf(label_str, ITEM_LABEL_LENGTH,
2227 "%s: %s", hfinfo->name, (char*) fvalue_get(fi->value));
2231 g_error("hfinfo->type %d (%s) not handled\n",
2233 ftype_name(hfinfo->type));
2234 g_assert_not_reached();
2240 fill_label_uint64(field_info *fi, gchar *label_str)
2242 unsigned char *bytes;
2243 header_field_info *hfinfo = fi->hfinfo;
2245 bytes=fvalue_get(fi->value);
2246 switch(hfinfo->display){
2248 snprintf(label_str, ITEM_LABEL_LENGTH,
2249 "%s: %s", hfinfo->name,
2253 snprintf(label_str, ITEM_LABEL_LENGTH,
2254 "%s: %s", hfinfo->name,
2258 g_assert_not_reached();
2264 fill_label_int64(field_info *fi, gchar *label_str)
2266 unsigned char *bytes;
2267 header_field_info *hfinfo = fi->hfinfo;
2269 bytes=fvalue_get(fi->value);
2270 switch(hfinfo->display){
2272 snprintf(label_str, ITEM_LABEL_LENGTH,
2273 "%s: %s", hfinfo->name,
2277 snprintf(label_str, ITEM_LABEL_LENGTH,
2278 "%s: %s", hfinfo->name,
2282 g_assert_not_reached();
2288 fill_label_boolean(field_info *fi, gchar *label_str)
2290 char *p = label_str;
2291 int bitfield_byte_length = 0, bitwidth;
2292 guint32 unshifted_value;
2295 header_field_info *hfinfo = fi->hfinfo;
2296 static true_false_string default_tf = { "True", "False" };
2297 true_false_string *tfstring = &default_tf;
2299 if (hfinfo->strings) {
2300 tfstring = (struct true_false_string*) hfinfo->strings;
2303 value = fvalue_get_integer(fi->value);
2304 if (hfinfo->bitmask) {
2305 /* Figure out the bit width */
2306 bitwidth = hfinfo_bitwidth(hfinfo);
2309 unshifted_value = value;
2310 if (hfinfo->bitshift > 0) {
2311 unshifted_value <<= hfinfo->bitshift;
2314 /* Create the bitfield first */
2315 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
2316 bitfield_byte_length = p - label_str;
2319 /* Fill in the textual info */
2320 snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
2321 "%s: %s", hfinfo->name,
2322 value ? tfstring->true_string : tfstring->false_string);
2326 /* Fills data for bitfield ints with val_strings */
2328 fill_label_enumerated_bitfield(field_info *fi, gchar *label_str)
2330 char *format = NULL, *p;
2331 int bitfield_byte_length, bitwidth;
2332 guint32 unshifted_value;
2335 header_field_info *hfinfo = fi->hfinfo;
2337 /* Figure out the bit width */
2338 bitwidth = hfinfo_bitwidth(hfinfo);
2340 /* Pick the proper format string */
2341 format = hfinfo_uint_vals_format(hfinfo);
2344 unshifted_value = fvalue_get_integer(fi->value);
2345 value = unshifted_value;
2346 if (hfinfo->bitshift > 0) {
2347 unshifted_value <<= hfinfo->bitshift;
2350 /* Create the bitfield first */
2351 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
2352 bitfield_byte_length = p - label_str;
2354 /* Fill in the textual info using stored (shifted) value */
2355 snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
2356 format, hfinfo->name,
2357 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
2361 fill_label_numeric_bitfield(field_info *fi, gchar *label_str)
2363 char *format = NULL, *p;
2364 int bitfield_byte_length, bitwidth;
2365 guint32 unshifted_value;
2368 header_field_info *hfinfo = fi->hfinfo;
2370 /* Figure out the bit width */
2371 bitwidth = hfinfo_bitwidth(hfinfo);
2373 /* Pick the proper format string */
2374 format = hfinfo_uint_format(hfinfo);
2377 unshifted_value = fvalue_get_integer(fi->value);
2378 value = unshifted_value;
2379 if (hfinfo->bitshift > 0) {
2380 unshifted_value <<= hfinfo->bitshift;
2383 /* Create the bitfield using */
2384 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
2385 bitfield_byte_length = p - label_str;
2387 /* Fill in the textual info using stored (shifted) value */
2388 snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
2389 format, hfinfo->name, value);
2393 fill_label_enumerated_uint(field_info *fi, gchar *label_str)
2395 char *format = NULL;
2396 header_field_info *hfinfo = fi->hfinfo;
2399 /* Pick the proper format string */
2400 format = hfinfo_uint_vals_format(hfinfo);
2402 value = fvalue_get_integer(fi->value);
2404 /* Fill in the textual info */
2405 snprintf(label_str, ITEM_LABEL_LENGTH,
2406 format, hfinfo->name,
2407 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
2411 fill_label_uint(field_info *fi, gchar *label_str)
2413 char *format = NULL;
2414 header_field_info *hfinfo = fi->hfinfo;
2417 /* Pick the proper format string */
2418 format = hfinfo_uint_format(hfinfo);
2419 value = fvalue_get_integer(fi->value);
2421 /* Fill in the textual info */
2422 snprintf(label_str, ITEM_LABEL_LENGTH,
2423 format, hfinfo->name, value);
2427 fill_label_enumerated_int(field_info *fi, gchar *label_str)
2429 char *format = NULL;
2430 header_field_info *hfinfo = fi->hfinfo;
2433 /* Pick the proper format string */
2434 format = hfinfo_int_vals_format(hfinfo);
2435 value = fvalue_get_integer(fi->value);
2437 /* Fill in the textual info */
2438 snprintf(label_str, ITEM_LABEL_LENGTH,
2439 format, hfinfo->name,
2440 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
2444 fill_label_int(field_info *fi, gchar *label_str)
2446 char *format = NULL;
2447 header_field_info *hfinfo = fi->hfinfo;
2450 /* Pick the proper format string */
2451 format = hfinfo_int_format(hfinfo);
2452 value = fvalue_get_integer(fi->value);
2454 /* Fill in the textual info */
2455 snprintf(label_str, ITEM_LABEL_LENGTH,
2456 format, hfinfo->name, value);
2460 hfinfo_bitwidth(header_field_info *hfinfo)
2464 if (!hfinfo->bitmask) {
2468 switch(hfinfo->type) {
2486 bitwidth = hfinfo->display; /* hacky? :) */
2489 g_assert_not_reached();
2496 hfinfo_uint_vals_format(header_field_info *hfinfo)
2498 char *format = NULL;
2500 switch(hfinfo->display) {
2502 case BASE_BIN: /* I'm lazy */
2503 format = "%s: %s (%u)";
2505 case BASE_OCT: /* I'm lazy */
2506 format = "%s: %s (%o)";
2509 switch(hfinfo->type) {
2511 format = "%s: %s (0x%02x)";
2514 format = "%s: %s (0x%04x)";
2517 format = "%s: %s (0x%06x)";
2520 format = "%s: %s (0x%08x)";
2523 g_assert_not_reached();
2528 g_assert_not_reached();
2535 hfinfo_uint_format(header_field_info *hfinfo)
2537 char *format = NULL;
2539 /* Pick the proper format string */
2540 switch(hfinfo->display) {
2542 case BASE_BIN: /* I'm lazy */
2545 case BASE_OCT: /* I'm lazy */
2549 switch(hfinfo->type) {
2551 format = "%s: 0x%02x";
2554 format = "%s: 0x%04x";
2557 format = "%s: 0x%06x";
2560 format = "%s: 0x%08x";
2563 g_assert_not_reached();
2568 g_assert_not_reached();
2575 hfinfo_int_vals_format(header_field_info *hfinfo)
2577 char *format = NULL;
2579 switch(hfinfo->display) {
2581 case BASE_BIN: /* I'm lazy */
2582 format = "%s: %s (%d)";
2584 case BASE_OCT: /* I'm lazy */
2585 format = "%s: %s (%o)";
2588 switch(hfinfo->type) {
2590 format = "%s: %s (0x%02x)";
2593 format = "%s: %s (0x%04x)";
2596 format = "%s: %s (0x%06x)";
2599 format = "%s: %s (0x%08x)";
2602 g_assert_not_reached();
2607 g_assert_not_reached();
2614 hfinfo_int_format(header_field_info *hfinfo)
2616 char *format = NULL;
2618 /* Pick the proper format string */
2619 switch(hfinfo->display) {
2621 case BASE_BIN: /* I'm lazy */
2624 case BASE_OCT: /* I'm lazy */
2628 switch(hfinfo->type) {
2630 format = "%s: 0x%02x";
2633 format = "%s: 0x%04x";
2636 format = "%s: 0x%06x";
2639 format = "%s: 0x%08x";
2642 g_assert_not_reached();
2647 g_assert_not_reached();
2656 proto_registrar_n(void)
2658 return gpa_hfinfo->len;
2662 proto_registrar_get_name(int n)
2664 header_field_info *hfinfo;
2666 hfinfo = proto_registrar_get_nth(n);
2668 return hfinfo->name;
2674 proto_registrar_get_abbrev(int n)
2676 header_field_info *hfinfo;
2678 hfinfo = proto_registrar_get_nth(n);
2680 return hfinfo->abbrev;
2686 proto_registrar_get_ftype(int n)
2688 header_field_info *hfinfo;
2690 hfinfo = proto_registrar_get_nth(n);
2692 return hfinfo->type;
2698 proto_registrar_get_parent(int n)
2700 header_field_info *hfinfo;
2702 hfinfo = proto_registrar_get_nth(n);
2704 return hfinfo->parent;
2710 proto_registrar_is_protocol(int n)
2712 header_field_info *hfinfo;
2714 hfinfo = proto_registrar_get_nth(n);
2716 return (hfinfo->parent == -1 ? TRUE : FALSE);
2721 /* Returns length of field in packet (not necessarily the length
2722 * in our internal representation, as in the case of IPv4).
2723 * 0 means undeterminable at time of registration
2724 * -1 means the field is not registered. */
2726 proto_registrar_get_length(int n)
2728 header_field_info *hfinfo;
2730 hfinfo = proto_registrar_get_nth(n);
2734 return ftype_length(hfinfo->type);
2738 /* =================================================================== */
2739 /* used when calling proto search functions */
2741 header_field_info *target;
2742 const guint8 *packet_data;
2744 gboolean halt_on_first_hit;
2745 GNodeTraverseFunc traverse_func; /* for traverse_subtree_for_field() */
2747 GPtrArray *ptr_array;
2750 } proto_tree_search_info;
2752 /* Looks for a protocol at the top layer of the tree. The protocol can occur
2753 * more than once, for those encapsulated protocols. For each protocol subtree
2754 * that is found, the callback function is called.
2757 proto_find_protocol_multi(proto_tree* tree, GNodeTraverseFunc callback,
2758 proto_tree_search_info *sinfo)
2760 g_assert(callback != NULL);
2761 g_node_traverse((GNode*)tree, G_IN_ORDER, G_TRAVERSE_ALL, 2, callback, (gpointer*)sinfo);
2764 /* Calls a traversal function for all subtrees.
2767 traverse_subtree_for_field(GNode *node, gpointer data)
2769 field_info *fi = PITEM_FINFO(node);
2770 proto_tree_search_info *sinfo = (proto_tree_search_info*) data;
2772 if (fi) { /* !fi == the top most container node which holds nothing */
2773 g_node_traverse(node, G_IN_ORDER, G_TRAVERSE_ALL, -1,
2774 sinfo->traverse_func, sinfo);
2775 if (sinfo->result.node)
2776 return sinfo->halt_on_first_hit; /* halt? continue? */
2778 return FALSE; /* keep traversing */
2781 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
2782 * it exists anywhere, or FALSE if it exists nowhere. */
2784 proto_check_for_protocol_or_field(proto_tree* tree, int id)
2786 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
2791 else if (g_ptr_array_len(ptrs) > 0) {
2799 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
2800 * This only works if the hfindex was "primed" before the dissection
2801 * took place, as we just pass back the already-created GPtrArray*.
2802 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
2805 proto_get_finfo_ptr_array(proto_tree *tree, int id)
2807 return g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
2808 GINT_TO_POINTER(id));
2819 check_for_offset(GNode *node, gpointer data)
2821 field_info *fi = PITEM_FINFO(node);
2822 offset_search_t *offsearch = data;
2824 /* !fi == the top most container node which holds nothing */
2825 if (fi && fi->visible && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
2826 if (offsearch->offset >= (guint) fi->start &&
2827 offsearch->offset < (guint) (fi->start + fi->length)) {
2829 offsearch->finfo = fi;
2830 return FALSE; /* keep traversing */
2833 return FALSE; /* keep traversing */
2836 /* Search a proto_tree backwards (from leaves to root) looking for the field
2837 * whose start/length occupies 'offset' */
2838 /* XXX - I couldn't find an easy way to search backwards, so I search
2839 * forwards, w/o stopping. Therefore, the last finfo I find will the be
2840 * the one I want to return to the user. This algorithm is inefficient
2841 * and could be re-done, but I'd have to handle all the children and
2842 * siblings of each node myself. When I have more time I'll do that.
2845 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
2847 offset_search_t offsearch;
2849 offsearch.offset = offset;
2850 offsearch.finfo = NULL;
2851 offsearch.tvb = tvb;
2853 g_node_traverse((GNode*)tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
2854 check_for_offset, &offsearch);
2856 return offsearch.finfo;
2863 /* Dumps the contents of the registration database to stdout. An indepedent program can take
2864 * this output and format it into nice tables or HTML or whatever.
2866 * There is one record per line. Each record is either a protocol or a header
2867 * field, differentiated by the first field. The fields are tab-delimited.
2872 * Field 2 = protocol name
2873 * Field 3 = protocol abbreviation
2878 * Field 2 = field name
2879 * Field 3 = field abbreviation
2880 * Field 4 = type ( textual representation of the the ftenum type )
2881 * Field 5 = parent protocol abbreviation
2884 proto_registrar_dump(void)
2886 header_field_info *hfinfo, *parent_hfinfo;
2888 const char *enum_name;
2890 len = gpa_hfinfo->len;
2891 for (i = 0; i < len ; i++) {
2892 hfinfo = proto_registrar_get_nth(i);
2895 * Skip fields with zero-length names or abbreviations;
2896 * the pseudo-field for "proto_tree_add_text()" is such
2897 * a field, and we don't want it in the list of filterable
2901 * XXX - perhaps the name and abbrev field should be null
2902 * pointers rather than null strings for that pseudo-field,
2903 * but we'd have to add checks for null pointers in some
2904 * places if we did that.
2906 * Or perhaps protocol tree items added with
2907 * "proto_tree_add_text()" should have -1 as the field index,
2908 * with no pseudo-field being used, but that might also
2909 * require special checks for -1 to be added.
2911 if (strlen(hfinfo->name) == 0 || strlen(hfinfo->abbrev) == 0)
2914 /* format for protocols */
2915 if (proto_registrar_is_protocol(i)) {
2916 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
2918 /* format for header fields */
2921 * If this field isn't at the head of the list of
2922 * fields with this name, skip this field - all
2923 * fields with the same name are really just versions
2924 * of the same field stored in different bits, and
2925 * should have the same type/radix/value list, and
2926 * just differ in their bit masks. (If a field isn't
2927 * a bitfield, but can be, say, 1 or 2 bytes long,
2928 * it can just be made FT_UINT16, meaning the
2929 * *maximum* length is 2 bytes, and be used
2932 if (hfinfo->same_name_prev != NULL)
2935 parent_hfinfo = proto_registrar_get_nth(hfinfo->parent);
2936 g_assert(parent_hfinfo);
2938 enum_name = ftype_name(hfinfo->type);
2939 printf("F\t%s\t%s\t%s\t%s\n", hfinfo->name, hfinfo->abbrev,
2940 enum_name,parent_hfinfo->abbrev);
2946 hfinfo_numeric_format(header_field_info *hfinfo)
2948 char *format = NULL;
2950 /* Pick the proper format string */
2951 switch(hfinfo->display) {
2953 case BASE_OCT: /* I'm lazy */
2954 case BASE_BIN: /* I'm lazy */
2955 switch(hfinfo->type) {
2960 format = "%s == %u";
2966 format = "%s == %d";
2969 g_assert_not_reached();
2974 switch(hfinfo->type) {
2976 format = "%s == 0x%02x";
2979 format = "%s == 0x%04x";
2982 format = "%s == 0x%06x";
2985 format = "%s == 0x%08x";
2988 g_assert_not_reached();
2993 g_assert_not_reached();
3000 * Returns TRUE if we can do a "match selected" on the field, FALSE
3004 proto_can_match_selected(field_info *finfo)
3006 header_field_info *hfinfo;
3008 hfinfo = finfo->hfinfo;
3011 switch(hfinfo->type) {
3029 case FT_ABSOLUTE_TIME:
3030 case FT_RELATIVE_TIME:
3034 * These all have values, so we can match.
3040 * This doesn't have a value, so we'd match
3041 * on the raw bytes at this address;
3042 * however, if the length is 0, there's nothing
3043 * to match, so we can't match.
3045 return (finfo->length != 0);
3050 proto_alloc_dfilter_string(field_info *finfo, guint8 *pd)
3052 header_field_info *hfinfo;
3054 char *buf, *stringified, *format, *ptr, *value_str;
3058 hfinfo = finfo->hfinfo;
3060 abbrev_len = strlen(hfinfo->abbrev);
3062 switch(hfinfo->type) {
3065 dfilter_len = abbrev_len + 6;
3066 buf = g_malloc0(dfilter_len);
3067 snprintf(buf, dfilter_len, "%s == %s",
3069 fvalue_get_integer(finfo->value) ? "1" : "0");
3080 dfilter_len = abbrev_len + 20;
3081 buf = g_malloc0(dfilter_len);
3082 format = hfinfo_numeric_format(hfinfo);
3083 snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer(finfo->value));
3087 stringified = u64toa(fvalue_get(finfo->value));
3088 dfilter_len = abbrev_len + 4 + strlen(stringified) +1;
3089 buf = g_malloc0(dfilter_len);
3090 snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev,
3095 stringified = i64toa(fvalue_get(finfo->value));
3096 dfilter_len = abbrev_len + 4 + strlen(stringified) +1;
3097 buf = g_malloc0(dfilter_len);
3098 snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev,
3103 dfilter_len = abbrev_len + 4 + 15 + 1;
3104 buf = g_malloc0(dfilter_len);
3105 snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev,
3106 ipv4_addr_str(fvalue_get(finfo->value)));
3110 dfilter_len = abbrev_len + 15;
3111 buf = g_malloc0(dfilter_len);
3112 snprintf(buf, dfilter_len, "%s == 0x%08x", hfinfo->abbrev,
3113 fvalue_get_integer(finfo->value));
3117 stringified = ip6_to_str((struct e_in6_addr*) fvalue_get(finfo->value));
3118 dfilter_len = abbrev_len + 4 + strlen(stringified) + 1;
3119 buf = g_malloc0(dfilter_len);
3120 snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev,
3125 dfilter_len = abbrev_len + 30;
3126 buf = g_malloc0(dfilter_len);
3127 snprintf(buf, dfilter_len, "%s == %f", hfinfo->abbrev,
3128 fvalue_get_floating(finfo->value));
3132 dfilter_len = abbrev_len + 22;
3133 buf = g_malloc0(dfilter_len);
3134 snprintf(buf, dfilter_len, "%s == %s",
3136 ether_to_str(fvalue_get(finfo->value)));
3139 case FT_ABSOLUTE_TIME:
3141 abs_time_to_str((nstime_t *)fvalue_get(finfo->value));
3142 dfilter_len = abbrev_len + strlen(value_str) + 7;
3143 buf = g_malloc0(dfilter_len);
3144 snprintf(buf, dfilter_len, "%s == \"%s\"",
3145 hfinfo->abbrev, value_str);
3148 case FT_RELATIVE_TIME:
3150 rel_time_to_secs_str((nstime_t *)fvalue_get(finfo->value));
3151 dfilter_len = abbrev_len + strlen(value_str) + 4;
3152 buf = g_malloc0(dfilter_len);
3153 snprintf(buf, dfilter_len, "%s == %s",
3154 hfinfo->abbrev, value_str);
3164 value_str = fvalue_get(finfo->value);
3165 dfilter_len = abbrev_len + strlen(value_str) + 7;
3166 buf = g_malloc0(dfilter_len);
3167 snprintf(buf, dfilter_len, "%s == \"%s\"",
3168 hfinfo->abbrev, value_str);
3172 dfilter_len = finfo->length*3 - 1;
3173 dfilter_len += abbrev_len + 7;
3174 buf = g_malloc0(dfilter_len);
3175 snprintf(buf, dfilter_len, "%s == %s",
3177 bytes_to_str_punct(fvalue_get(finfo->value), finfo->length,':'));
3181 c = pd + finfo->start;
3182 buf = g_malloc0(32 + finfo->length * 3);
3185 sprintf(ptr, "frame[%d] == ", finfo->start);
3186 ptr = buf+strlen(buf);
3188 for (i=0;i<finfo->length; i++) {
3190 sprintf(ptr, "%02x", *c++);
3193 sprintf(ptr, ":%02x", *c++);
3195 ptr = buf+strlen(buf);