*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
__DISSECTOR_ASSERT (expression, __FILE__, __LINE__))) \
__DISSECTOR_ASSERT_STATIC_ANALYSIS_HINT(expression)
+/**
+ * Same as DISSECTOR_ASSERT(), but takes an extra 'hint' parameter that
+ * can be used to provide information as to why the assertion might fail.
+ *
+ * @param expression expression to test in the assertion
+ * @param hint message providing extra information
+ */
+#define DISSECTOR_ASSERT_HINT(expression, hint) \
+ ((void) ((expression) ? (void)0 : \
+ __DISSECTOR_ASSERT_HINT (expression, __FILE__, __LINE__, hint))) \
+ __DISSECTOR_ASSERT_STATIC_ANALYSIS_HINT(expression)
+
#if 0
/* win32: using a debug breakpoint (int 3) can be very handy while debugging,
* as the assert handling of GTK/GLib is currently not very helpful */
ep_strdup_printf("%s:%u: failed assertion \"%s\"", \
file, lineno, __DISSECTOR_ASSERT_STRINGIFY(expression))))
+#define __DISSECTOR_ASSERT_HINT(expression, file, lineno, hint) \
+ (REPORT_DISSECTOR_BUG( \
+ ep_strdup_printf("%s:%u: failed assertion \"%s\" (%s)", \
+ file, lineno, __DISSECTOR_ASSERT_STRINGIFY(expression), hint)))
+
/*
* The encoding of a field of a particular type may involve more
* than just whether it's big-endian or little-endian and its size.
* ENC_LITTLE_ENDIAN as 0x80000000 - we're using the high-order bit
* so that we could put a field type and/or a value such as a character
* encoding in the lower bits.
- *
- * For protocols (FT_PROTOCOL), aggregate items with subtrees (FT_NONE),
- * opaque byte-array fields (FT_BYTES), and other fields where there
- * is no choice of encoding (either because it's "just a bucket
- * of bytes" or because the encoding is completely fixed), we
- * have ENC_NA (for "Not Applicable").
*/
#define ENC_BIG_ENDIAN 0x00000000
#define ENC_LITTLE_ENDIAN 0x80000000
* For backwards compatibility, we interpret an encoding of 1 as meaning
* "little-endian timespec", so that passing TRUE is interpreted as that.
*/
-#define ENC_TIME_TIMESPEC 0
-#define ENC_TIME_NTP 2
+#define ENC_TIME_TIMESPEC 0x00000000
+#define ENC_TIME_NTP 0x00000002
+
+/*
+ * Historically, the only place the representation mattered for strings
+ * was with FT_UINT_STRINGs, where we had FALSE for the string length
+ * being big-endian and TRUE for it being little-endian.
+ *
+ * We now have encoding values for the character encoding. The encoding
+ * values are encoded in all but the top bit (which is the byte-order
+ * bit, required for FT_UINT_STRING and for UCS-2 and UTF-16 strings)
+ * and the bottom bit (which we ignore for now so that programs that
+ * pass TRUE for the encoding just do ASCII). (The encodings are given
+ * directly as even numbers in hex, so that make-init-lua.pl can just
+ * turn them into numbers for use in init.lua.)
+ *
+ * We don't yet process ASCII and UTF-8 differently. Ultimately, for
+ * ASCII, all bytes with the 8th bit set should be mapped to some "this
+ * is not a valid character" code point, as ENC_ASCII should mean "this
+ * is ASCII, not some extended variant thereof". We should also map
+ * 0x00 to that as well - null-terminated and null-padded strings
+ * never have NULs in them, but counted strings might. (Either that,
+ * or the values for strings should be counted, not null-terminated.)
+ * For UTF-8, invalid UTF-8 sequences should be mapped to the same
+ * code point.
+ *
+ * We also don't process UTF-16 or UCS-2 differently - we don't
+ * handle surrogate pairs, and don't handle 2-byte values that
+ * aren't valid in UTF-16 or UCS-2 strings.
+ *
+ * For display, perhaps we should also map control characters to the
+ * Unicode glyphs showing the name of the control character in small
+ * caps, diagonally. (Unfortunately, those only exist for C0, not C1.)
+ */
+#define ENC_CHARENCODING_MASK 0x7FFFFFFE /* mask out byte-order bits */
+#define ENC_ASCII 0x00000000
+#define ENC_UTF_8 0x00000002
+#define ENC_UTF_16 0x00000004
+#define ENC_UCS_2 0x00000006
+#define ENC_EBCDIC 0x00000008
+
+/*
+ * TODO:
+ *
+ * These could probably be used by existing code:
+ *
+ * ENC_UCS_4 - UCS-4
+ * ENC_ISO_8859_1 - ISO 8859/1
+ * ENC_ISO_8859_8 - ISO 8859/8
+ * - "IBM MS DBCS"
+ * - JIS C 6226
+ * 7-bit encodings such as ETSI 03.38 (GSM SMS character set
+ * (see packet-ansi_337.c, packet-gsm_a_dtap.c, packet-gsm_map.c,
+ * packet-gsm_sms.c)?
+ *
+ * See also packet-bacapp.c.
+ */
+/*
+ * For protocols (FT_PROTOCOL), aggregate items with subtrees (FT_NONE),
+ * opaque byte-array fields (FT_BYTES), and other fields where there
+ * is no choice of encoding (either because it's "just a bucket
+ * of bytes" or because the encoding is completely fixed), we
+ * have ENC_NA (for "Not Applicable").
+ */
#define ENC_NA 0x00000000
/* Values for header_field_info.display */
/** information describing a header field */
struct _header_field_info {
/* ---------- set by dissector --------- */
- const char *name; /**< full name of this field */
- const char *abbrev; /**< abbreviated name of this field */
- enum ftenum type; /**< field type, one of FT_ (from ftypes.h) */
- int display; /**< one of BASE_, or field bit-width if FT_BOOLEAN and non-zero bitmask */
- const void *strings; /**< value_string, range_string or true_false_string,
+ const char *name; /**< [FIELDNAME] full name of this field */
+ const char *abbrev; /**< [FIELDABBREV] abbreviated name of this field */
+ enum ftenum type; /**< [FIELDTYPE] field type, one of FT_ (from ftypes.h) */
+ int display; /**< [FIELDDISPLAY] one of BASE_, or field bit-width if FT_BOOLEAN and non-zero bitmask */
+ const void *strings; /**< [FIELDCONVERT] value_string, range_string or true_false_string,
typically converted by VALS(), RVALS() or TFS().
If this is an FT_PROTOCOL then it points to the
associated protocol_t structure */
- guint32 bitmask; /**< bitmask of interesting bits */
- const char *blurb; /**< Brief description of field */
+ guint32 bitmask; /**< [BITMASK] bitmask of interesting bits */
+ const char *blurb; /**< [FIELDDESCR] Brief description of field */
/* ------- set by proto routines (prefilled by HFILL macro, see below) ------ */
int id; /**< Field ID */
} field_info;
+/*
+ * This structure describes one segment of a split-bits item
+ * crumb_bit_offset is the bit offset in the input tvb of the first (most significant) bit of this crumb
+ * crumb_bit_length is the number of contiguous bits of this crumb.
+ * The first element of an array of bits_specs describes the most significant crumb of the output value.
+ * The second element of an array of bits_specs describes the next-most significant crumb of the output value, etc.
+ * The array is terminated by a sentinal entry with crumb_bit_length of 0.
+*/
+typedef struct
+{
+ guint crumb_bit_offset;
+ guint8 crumb_bit_length;
+}crumb_spec_t;
+
/*
* Flag fields. Do not assign values greater than 0x00000080 unless you
* shuffle the expert information upward; see below.
/** The protocol field value is in big endian */
#define FI_BIG_ENDIAN 0x00000010
/** Field value start from nth bit (values from 0x20 - 0x100) */
-#define FI_BITS_OFFSET(n) ((n & 7) << 5)
+#define FI_BITS_OFFSET(n) (((n) & 7) << 5)
/** Field value takes n bits (values from 0x100 - 0x4000) */
/* if 0, it means that field takes fi->length * 8 */
-#define FI_BITS_SIZE(n) ((n & 63) << 8)
+#define FI_BITS_SIZE(n) (((n) & 63) << 8)
/** convenience macro to get field_info.flags */
-#define FI_GET_FLAG(fi, flag) ((fi) ? (fi->flags & flag) : 0)
+#define FI_GET_FLAG(fi, flag) ((fi) ? ((fi)->flags & (flag)) : 0)
/** convenience macro to set field_info.flags */
#define FI_SET_FLAG(fi, flag) \
do { \
if (fi) \
(fi)->flags = (fi)->flags | (flag); \
} while(0)
+/** convenience macro to reset field_info.flags */
+#define FI_RESET_FLAG(fi, flag) \
+ do { \
+ if (fi) \
+ (fi)->flags = (fi)->flags & ~(flag); \
+ } while(0)
#define FI_GET_BITS_OFFSET(fi) (FI_GET_FLAG(fi, FI_BITS_OFFSET(7)) >> 5)
#define FI_GET_BITS_SIZE(fi) (FI_GET_FLAG(fi, FI_BITS_SIZE(63)) >> 8)
* in the protocol tree points to the same copy. */
typedef struct {
GHashTable *interesting_hfids;
- gboolean visible;
- gboolean fake_protocols;
- gint count;
+ gboolean visible;
+ gboolean fake_protocols;
+ gint count;
+ struct _packet_info *pinfo;
+ field_info *fi_tmp;
} tree_data_t;
/** Each proto_tree, proto_item is one of these. */
/* expert severities */
#define PI_SEVERITY_MASK 0x00F00000 /**< mask usually for internal use only! */
+/** Packet is commented */
+#define PI_COMMENT 0x00100000
/** Usual workflow, e.g. TCP connection establishing */
#define PI_CHAT 0x00200000
/** Notable messages, e.g. an application returned an "usual" error code like HTTP 404 */
/* expert "event groups" */
#define PI_GROUP_MASK 0xFF000000 /**< mask usually for internal use only! */
/** The protocol field has a bad checksum, usually PI_WARN */
-
#define PI_CHECKSUM 0x01000000
/** The protocol field indicates a sequence problem (e.g. TCP window is zero) */
#define PI_SEQUENCE 0x02000000
#define PI_DEBUG 0x08000000
/** The protocol field violates a protocol specification, usually PI_WARN */
#define PI_PROTOCOL 0x09000000
-/* The protocol field indicates a security probem (e.g. unsecure implementation) */
+/** The protocol field indicates a security probem (e.g. unsecure implementation) */
#define PI_SECURITY 0x0a000000
+/** The protocol field indicates a packet comment */
+#define PI_COMMENTS_GROUP 0x0b000000
/* add more, see http://wiki.wireshark.org/Development/ExpertInfo */
do { \
if (proto_item) \
FI_SET_FLAG(PITEM_FINFO(proto_item), FI_HIDDEN); \
- } while(0)
+ } while(0)
+/** mark this protocol field to be visible from the protocol tree display */
+#define PROTO_ITEM_SET_VISIBLE(proto_item) \
+ do { \
+ if (proto_item) \
+ FI_RESET_FLAG(PITEM_FINFO(proto_item), FI_HIDDEN); \
+ } while(0)
+
/** is this protocol field generated by Wireshark (and not read from the packet data)? */
#define PROTO_ITEM_IS_GENERATED(proto_item) \
((proto_item) ? FI_GET_FLAG(PITEM_FINFO(proto_item), FI_GENERATED) : 0)
*/
extern gboolean proto_field_is_referenced(proto_tree *tree, int proto_id);
-
-
/** Create a subtree under an existing item.
@param ti the parent item of the new subtree
@param idx one of the ett_ array elements registered with proto_register_subtree_array()
@return the new subtree */
-extern proto_tree* proto_item_add_subtree(proto_item *ti, const gint idx);
+extern proto_tree* proto_item_add_subtree(proto_item *ti, const gint idx) G_GNUC_WARN_UNUSED_RESULT;
/** Get an existing subtree under an item.
@param ti the parent item of the subtree
/** Creates a new proto_tree root.
@return the new tree root */
-extern proto_tree* proto_tree_create_root(void);
+extern proto_tree* proto_tree_create_root(struct _packet_info *pinfo);
/** Clear memory for entry proto_tree. Clears proto_tree struct also.
@param tree the tree to free */
proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, const guint8* value_ptr, const char *format, ...) G_GNUC_PRINTF(7,8);
+/** Add a FT_AX25 to a proto_tree.
+ @param tree the tree to append this item to
+ @param hfindex field index
+ @param tvb the tv buffer of the current data
+ @param start start of data in tvb
+ @param length length of data in tvb
+ @param value data to display
+ @return the newly created item */
+extern proto_item *
+proto_tree_add_ax25(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+ gint length, const guint8* value);
+
/** Add a FT_ETHER to a proto_tree.
@param tree the tree to append this item to
@param hfindex field index
proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, const char* value, const char *format, ...) G_GNUC_PRINTF(7,8);
+extern proto_item *
+proto_tree_add_unicode_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+ gint length, const char* value);
+
/** Add a FT_BOOLEAN to a proto_tree.
@param tree the tree to append this item to
@param hfindex field index
proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, gint64 value, const char *format, ...) G_GNUC_PRINTF(7,8);
+/** Add a FT_EUI64 to a proto_tree.
+ @param tree the tree to append this item to
+ @param hfindex field index
+ @param tvb the tv buffer of the current data
+ @param start start of data in tvb
+ @param length length of data in tvb
+ @param value data to display
+ @return the newly created item */
+extern proto_item *
+proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+ gint length, const guint64 value);
+
+/** Add a formatted FT_EUI64 to a proto_tree, with the format generating
+ the string for the value and with the field name being included
+ automatically.
+ @param tree the tree to append this item to
+ @param hfindex field index
+ @param tvb the tv buffer of the current data
+ @param start start of data in tvb
+ @param length length of data in tvb
+ @param value data to display
+ @param format printf like format string
+ @param ... printf like parameters
+ @return the newly created item */
+extern proto_item *
+proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+ gint start, gint length, const guint64 value, const char *format, ...)
+ G_GNUC_PRINTF(7,8);
+
+/** Add a formatted FT_EUI64 to a proto_tree, with the format generating
+ the entire string for the entry, including any field name.
+ @param tree the tree to append this item to
+ @param hfindex field index
+ @param tvb the tv buffer of the current data
+ @param start start of data in tvb
+ @param length length of data in tvb
+ @param value data to display
+ @param format printf like format string
+ @param ... printf like parameters
+ @return the newly created item */
+extern proto_item *
+proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+ gint length, const guint64 value, const char *format, ...) G_GNUC_PRINTF(7,8);
+
+
/** Useful for quick debugging. Also sends string to STDOUT, so don't
leave call to this function in production code.
@param tree the tree to append the text to
extern void
proto_register_field_array(const int parent, hf_register_info *hf, const int num_records);
+/** Unregister an already registered field.
+ @param parent the protocol handle from proto_register_protocol()
+ @param hf_id the field to unregister */
+extern void
+proto_unregister_field (const int parent, gint hf_id);
+
/** Register a protocol subtree (ett) array.
@param indices array of ett indices
@param num_indices the number of records in indices */
/** Get enum ftenum FT_ of registered header_field number n.
@param n item # n (0-indexed)
@return the registered item */
-extern int proto_registrar_get_ftype(const int n);
+extern enum ftenum proto_registrar_get_ftype(const int n);
/** Get parent protocol of registered header_field number n.
@param n item # n (0-indexed)
* they return the item number of the protocol in question or the
* appropriate hfinfo pointer, and keep state in "*cookie". */
extern int proto_get_first_protocol(void **cookie);
+extern int proto_get_data_protocol(void *cookie);
extern int proto_get_next_protocol(void **cookie);
extern header_field_info *proto_get_first_protocol_field(const int proto_id, void **cookle);
extern header_field_info *proto_get_next_protocol_field(void **cookle);
* and the blurb. */
extern void proto_registrar_dump_fields(const int format);
+/** Dumps a glossary field types and descriptive names to STDOUT */
+extern void proto_registrar_dump_ftypes(void);
+
/** Points to the first element of an array of Booleans, indexed by
FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
FT_integer fields that have a value_string attached will have the
matched string displayed on the expansion line.
- @param little_endian big or little endian byte representation
+ @param encoding big or little endian byte representation (ENC_BIG_ENDIAN/ENC_LITTLE_ENDIAN)
@return the newly created item */
extern proto_item *
proto_tree_add_bitmask(proto_tree *tree, tvbuff_t *tvb, const guint offset,
- const int hf_hdr, const gint ett, const int **fields, const gboolean little_endian);
+ const int hf_hdr, const gint ett, const int **fields, const guint encoding);
/** Add a text with a subtree of bitfields.
@param tree the tree to append this item to
@param fallback field name if none of bitfields were usable
@param ett subtree index
@param fields NULL-terminated array of bitfield indexes
- @param little_endian big or little endian byte representation
- @param little_endian big or little endian byte representation
+ @param encoding big or little endian byte representation (ENC_BIG_ENDIAN/ENC_LITTLE_ENDIAN)
@param flags
@return the newly created item */
extern proto_item *
proto_tree_add_bitmask_text(proto_tree *tree, tvbuff_t *tvb, const guint offset, const guint len,
const char *name, const char *fallback,
- const gint ett, const int **fields, const gboolean little_endian, const int flags);
+ const gint ett, const int **fields, const guint encoding, const int flags);
#define BMT_NO_APPEND 0x01 /**< Don't change the title at all */
#define BMT_NO_INT 0x02 /**< Don't add integral (non-boolean) fields to title */
@param tvb the tv buffer of the current data
@param bit_offset start of data in tvb expressed in bits
@param no_of_bits length of data in tvb expressed in bits
- @param little_endian big or little endian byte representation
+ @param encoding data encoding
+ @return the newly created item */
+extern proto_item *
+proto_tree_add_bits_item(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits, const guint encoding);
+
+/** Add bits to a proto_tree, using the text label registered to that item.
+* The item is extracted from the tvbuff handed to it as a set
+* of crumbs (segments) of contiguous bits, specified by an
+* array of crumb_spec elements. The crumbs are assembled to
+* create the value. There may be any number of crumbs
+* specifying up to a total of 64 bits which may occur anywhere
+* within the tvb. If the span of the crumbs within the tvb is 4
+* octets or less, a bitmap of the crumbs is produced.
+ @param tree the tree to append this item to
+ @param hf_index field index. Fields for use with this function should have bitmask==0.
+ @param tvb the tv buffer of the current data
+ @param bit_offset of the first crumb in tvb expressed in bits
+ @param pointer to crumb_spec array
+ @param return_value if a pointer is passed here the value is returned.
@return the newly created item */
extern proto_item *
-proto_tree_add_bits_item(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, const gboolean little_endian);
+proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
+ const guint bit_offset, const crumb_spec_t *crumb_spec,
+ guint64 *return_value);
+
+
+/** Add bitmap text for a split-bits crumb to a proto_tree,
+* using the text label registered to an item. The bitmap is
+* extracted from the tvbuff handed to it as a crumb (segment)
+* of contiguous bits, specified by one of an array of
+* crumb_spec elements. This function is normally called once
+* per crumb, after the call to
+ proto_tree_add_split_bits_item_ret_val
+ @param tree the tree to append this item to
+ @param hf_index field index. Fields for use with this function should have bitmask==0.
+ @param tvb the tv buffer of the current data
+ @param bit_offset of the first crumb in tvb expressed in bits
+ @param pointer to crumb_spec array
+ @param index into the crumb_spec array for this crumb */
+void
+proto_tree_add_split_bits_crumb(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const guint bit_offset,
+ const crumb_spec_t *crumb_spec, guint16 crumb_index);
/** Add bits to a proto_tree, using the text label registered to that item.
The item is extracted from the tvbuff handed to it.
@param bit_offset start of data in tvb expressed in bits
@param no_of_bits length of data in tvb expressed in bits
@param return_value if a pointer is passed here the value is returned.
- @param little_endian big or little endian byte representation
+ @param encoding data encoding
@return the newly created item */
extern proto_item *
-proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, guint64 *return_value, const gboolean little_endian);
+proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits, guint64 *return_value, const guint encoding);
/** Add bits for a FT_UINT8, FT_UINT16, FT_UINT24 or FT_UINT32
header field to a proto_tree, with the format generating the
@param format printf like format string
@return the newly created item */
extern proto_item *
-proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits,
+proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits,
guint32 value, const char *format, ...) G_GNUC_PRINTF(7,8);
/** Add bits for a FT_BOOLEAN header field to a proto_tree, with
@param ... printf like parameters
@return the newly created item */
extern proto_item *
-proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits,
+proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits,
guint32 value, const char *format, ...) G_GNUC_PRINTF(7,8);
/** Add bits for a FT_INT8, FT_INT16, FT_INT24 or FT_INT32
@param ... printf like parameters
@return the newly created item */
extern proto_item *
-proto_tree_add_int_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits,
+proto_tree_add_int_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits,
gint32 value, const char *format, ...) G_GNUC_PRINTF(7,8);
/** Add bits for a FT_FLOAT header field to a proto_tree, with
@param ... printf like parameters
@return the newly created item */
extern proto_item *
-proto_tree_add_float_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits,
+proto_tree_add_float_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits,
float value, const char *format, ...) G_GNUC_PRINTF(7,8);
/** Check if given string is a valid field name