Make dissection of AVP: 3GPP-User-Location-Info(22) l=15 f=V-- vnd=TGPP val=303231...
[obnox/wireshark/wip.git] / epan / proto.h
index 98465ba2cfbdcc503c8635742ebb7eaf5a026d8e..0394e213446edb111c84d193a81b50d383b53bb3 100644 (file)
@@ -108,15 +108,32 @@ typedef struct _protocol protocol_t;
     abort() : \
     THROW_MESSAGE(DissectorError, message))
 
+/** Macro used to provide a hint to static analysis tools.
+ * (Currently only Visual C++.)
+ */
+#if _MSC_VER >= 1400
+/* XXX - Is there a way to say "quit checking at this point"? */
+#define __DISSECTOR_ASSERT_STATIC_ANALYSIS_HINT(expression) \
+  ; __analysis_assume(expression);
+#else
+#define __DISSECTOR_ASSERT_STATIC_ANALYSIS_HINT(expression)
+#endif
+
 /** Macro used for assertions in dissectors; it doesn't abort, it just
  * throws a DissectorError exception, with the assertion failure
  * message as a parameter, so that it can show up in the protocol tree.
  *
+ * NOTE: this should only be used to detect bugs in the dissector (e.g., logic
+ * conditions that shouldn't happen).  It should NOT be used for showing
+ * that a packet is malformed.  For that, use expert_infos instead.
+ *
  * @param expression expression to test in the assertion
  */
+
 #define DISSECTOR_ASSERT(expression)  \
   ((void) ((expression) ? (void)0 : \
-   __DISSECTOR_ASSERT (expression, __FILE__, __LINE__)))
+   __DISSECTOR_ASSERT (expression, __FILE__, __LINE__))) \
+   __DISSECTOR_ASSERT_STATIC_ANALYSIS_HINT(expression)
 
 #if 0
 /* win32: using a debug breakpoint (int 3) can be very handy while debugging,
@@ -127,6 +144,11 @@ typedef struct _protocol protocol_t;
 
 /** Same as DISSECTOR_ASSERT(), but will throw DissectorError exception
  * unconditionally, much like GLIB's g_assert_not_reached works.
+ *
+ * NOTE: this should only be used to detect bugs in the dissector (e.g., logic
+ * conditions that shouldn't happen).  It should NOT be used for showing
+ * that a packet is malformed.  For that, use expert_infos instead.
+ *
  */
 #define DISSECTOR_ASSERT_NOT_REACHED()  \
   (REPORT_DISSECTOR_BUG( \
@@ -187,16 +209,48 @@ typedef struct _protocol protocol_t;
  * 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.
+ */
+#define ENC_BIG_ENDIAN         0x00000000
+#define ENC_LITTLE_ENDIAN      0x80000000
+
+/*
+ * Historically FT_TIMEs were only timespecs; the only question was whether
+ * they were stored in big- or little-endian format.
  *
+ * 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
+
+/*
+ * 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.
+ *
+ * This is a quick and dirty hack for bug 6084, which doesn't require
+ * support for multiple character encodings in FT_UINT_STRING.  We
+ * introduce ENC_UTF_8 and ENC_EBCDIC, with ENC_UTF_8 being 0 and
+ * ENC_EBCDIC being the unlikely value 0x0EBCD000, and treat all values
+ * other than ENC_EBCDIC as UTF-8.  That way, no matter how a dissector
+ * not converted to use ENC_ values calculates the last argument to
+ * proto_tree_add_item(), it's unlikely to get EBCDIC.
+ *
+ * The value for ENC_EBCDIC is subject to change in a future release (or
+ * to replacement with multiple values for different flavors of EBCDIC).
+ * Additional encodings will also be provided.
+ */
+#define ENC_CHARENCODING_MASK  0x7FFFFFFE      /* mask out byte-order bits */
+#define ENC_UTF_8              0x00000000
+#define ENC_EBCDIC             0x0EBCD1C0
+
+/*
  * 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
-
 #define ENC_NA                 0x00000000
 
 /* Values for header_field_info.display */
@@ -242,16 +296,16 @@ typedef struct _header_field_info header_field_info;
 /** 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 */
@@ -321,7 +375,7 @@ typedef struct field_info {
 /** 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)
@@ -370,7 +424,7 @@ typedef proto_node proto_item;
  */
 
 /* expert severities */
-#define PI_SEVERITY_MASK       0x00F00000      /* mask usually for internal use only! */
+#define PI_SEVERITY_MASK       0x00F00000      /**< mask usually for internal use only! */
 /** 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 */
@@ -381,7 +435,7 @@ typedef proto_node proto_item;
 #define PI_ERROR               0x00800000
 
 /* expert "event groups" */
-#define PI_GROUP_MASK          0xFF000000      /* mask usually for internal use only! */
+#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
@@ -482,13 +536,11 @@ extern void proto_cleanup(void);
 */
 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
@@ -1392,6 +1444,51 @@ extern proto_item *
 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
@@ -1822,11 +1919,13 @@ proto_check_field_name(const gchar *field_name);
 /** Check if given string is a valid field name
  @param tree the tree to append this item to
  @param field_id the field id used for custom column
+ @param occurrence the occurrence of the field used for custom column
  @param result the buffer to fill with the field string
  @param expr the filter expression
  @param size the size of the string buffer */
 const gchar *
 proto_custom_set(proto_tree* tree, const int field_id,
+                             gint occurrence,
                              gchar *result,
                              gchar *expr, const int size );